We will use mainly three libraries.
library(jpeg)
library(ggplot2)
library(EBImage)
First we read the image and check the structure and dimensions.
img <- readJPEG("/Users/ayberkakgun/Desktop/doku5.jpg")
str(img)
## num [1:512, 1:512, 1:3] 0.776 0.796 0.82 0.808 0.792 ...
dim(img)
## [1] 512 512 3
The image can be displayed with “rasterImage” function.
plot(c(0, 512), c(0, 512), type = "n", xlab = "", ylab = "")
rasterImage(img, 0, 0, 512, 512)
We split the image to channels; red, blue and green.
For each channel, we take the average of the columns with “colMeans” and plot the average as a line for each channel.
We chose to crop the image horizontally for each channel and than substract the lower part from the upper part.
#Median Filtering
Let’s check the raw image once again.
We use medianFilter function to filter and display again. First for n=5.
Than for n=11.
and lastly for n=31.
##PART 2
library(imager)
library(gmodels)
library(magrittr)
img <- load.image("/Users/ayberkakgun/Desktop/doku5.jpg")
plot(img)
###2.1 At first, we transformed the image to a grayscale
gray<-grayscale(img)
gray %>% plot
After that, we took histogram of it in order to see pixel value distribution of our image.
hist(gray)
We draw normal distributed line and saw that normal distribution fits well to the shape of our pixel histogram.
xfit <- seq(min(gray), max(gray), length = 40)
yfit <- dnorm(xfit, mean = mean(gray), sd = sd(gray))
yfit <- yfit * diff(hist(gray)$mids[1:2]) * length(gray)
lines(xfit, yfit, col = "blue", lwd = 2)
###2.2 Estimated Normal distribution parameters from pixel data are as follows:
gray %>% summary
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.4509 0.6519 0.6912 0.6937 0.7313 0.9930
meanOfGray=mean(gray)
meanOfGray
## [1] 0.6936652
standardOfGray=sd(gray)
standardOfGray
## [1] 0.06032251
###2.3
At first, we found confidence interval, in other words upper and lower bounds.
error=qnorm(0.999)*sd(gray)
lowerLimit=meanOfGray-error
lowerLimit
## [1] 0.5072546
upperLimit=meanOfGray+error
upperLimit
## [1] 0.8800758
Then, we identified observations which are out of bounds.
bdf=as.data.frame(gray)
bdf %>% summary
## x y value
## Min. : 1.0 Min. : 1.0 Min. :0.4509
## 1st Qu.:128.8 1st Qu.:128.8 1st Qu.:0.6519
## Median :256.5 Median :256.5 Median :0.6912
## Mean :256.5 Mean :256.5 Mean :0.6937
## 3rd Qu.:384.2 3rd Qu.:384.2 3rd Qu.:0.7313
## Max. :512.0 Max. :512.0 Max. :0.9930
bdf %>% head
## x y value
## 1 1 1 0.7463137
## 2 2 1 0.7483529
## 3 3 1 0.7220392
## 4 4 1 0.7455686
## 5 5 1 0.7256471
## 6 6 1 0.6942353
lowerresult<-bdf["value"]<lowerLimit
summary(lowerresult)
## value
## Mode :logical
## FALSE:261985
## TRUE :159
upperresult<-bdf["value"]>upperLimit
summary(upperresult)
## value
## Mode :logical
## FALSE:260907
## TRUE :1237
We created new list which contains pixels that are out of these bounds in both sides and turned the list to a numeric form for following processes.
outIndexes<-list()
k<-1
for(i in 1:length(lowerresult)){
if(lowerresult[i]==TRUE){
outIndexes[k]<-i
k=k+1
}
}
for(i in 1:length(upperresult)){
if(upperresult[i]==TRUE){
outIndexes[k]<-i
k=k+1
}
}
outIndexes<-as.numeric(unlist(outIndexes))
After that, we changed the value of these pixels to zero.
for(i in 1:length(outIndexes)){
bdf[outIndexes[i],3]<-0
}
We displayed the new image and original image in a plot.
gray %>% dim
## [1] 512 512 1 1
zeroimage=as.cimg(bdf, dim=c(512,512,1,1))
op <- par(mfrow=c(1,2))
gray %>% plot(, xlim = c(1, width(.)), ylim = c(height(.), 1), rescale = FALSE, interpolate = FALSE)
zeroimage %>% plot(, xlim = c(1, width(.)), ylim = c(height(.), 1), rescale = FALSE, interpolate = FALSE)
par(op)
As we can see from the difference of two pictures, high valued pixels, in other words light areas, are changed to black color(0 pixel) because theywere outliers, they didn’t fit in confidence interval of the image’s pixel frequencies. Some low valued pixels changed too but as they were already too dark,an observer cannot recognize it. Those pixels also didn’t fit in confidence interval of the image’s pixel frequencies. So, we identified them as outliers and turned their values into zero which is black.
###2.4
At first, all patches are created and stored in a list.
dev.new(width=5120, height=5120)
image_listy <- imsplit(gray,"y",10)
image_listy
## Image list of size 10
image_list<-list()
for (i in 1:10){
image_list[[i]] = imsplit(image_listy[[i]],"x",10)
}
Then, for all patches, We repeated what we have done in the first three tasks in a loop. For each patch:
-Found confidence interval, in other words upper and lower bounds -Identified observations which are out of bounds -Created new list which contains pixels that are out of these bounds in both sides and turned the list to a numeric form for following processes -Changed the value of outlier pixels to zero which is black -Turned from list to cimg format.
image_list2 = list()
for (i in 1:10)
{
image_list2[[i]] = list()
for (j in 1:10)
{
error=qnorm(0.999)*sd(image_list[[i]][[j]])
lowerLimit=mean(image_list[[i]][[j]])-error
upperLimit=mean(image_list[[i]][[j]])+error
bdf=as.data.frame(image_list[[i]][[j]])
lowerresult<-bdf["value"]<lowerLimit
upperresult<-bdf["value"]>upperLimit
outIndexes<-list()
k<-1
for(l in 1:length(lowerresult)){
if(lowerresult[l]==TRUE){
outIndexes[k]<-l
k=k+1
}
}
for(l in 1:length(upperresult)){
if(upperresult[l]==TRUE){
outIndexes[k]<-l
k=k+1
}
}
outIndexes<-as.numeric(unlist(outIndexes))
if (length(outIndexes)>0){
for(l in 1:length(outIndexes)){
bdf[outIndexes[l],3]<-0
}
}
image_list2[[i]][[j]]=as.cimg(bdf,dim=dim(image_list[[i]][[j]]))
}
}
Then, we reunited marked patches and displayed it.
img2 = list()
for (i in 1:10)
{
img2[[i]]=imappend(image_list2[[i]],axis="x")
}
zeropatchimage = imappend(img2,axis="y") %>% plot
Finally, we displayed original image, marked image (third task) and united marked patches (this task) all together in order to see the difference.
op <- par(mfrow=c(1,3))
gray %>% plot(, xlim = c(1, width(.)), ylim = c(height(.), 1), rescale = FALSE, interpolate = FALSE)
zeroimage %>% plot(, xlim = c(1, width(.)), ylim = c(height(.), 1), rescale = FALSE, interpolate = FALSE)
zeropatchimage %>% plot(, xlim = c(1, width(.)), ylim = c(height(.), 1), rescale = FALSE, interpolate = FALSE)
par(op)
In this task, we detected local outliers (outliers within each patch) instead of looking high and low valued pixels in overall of original image. We have done local enhancement and enhanced overall contrast in the image more effectively. We divided the image into patches and only those patches were enhanced that fall in the window. Hence the intensities are distributed locally and contrast is enhanced based on the local area rather than the entire image. However, in this way,computational cost went very high due to its fully overlapped functions. Another possible problem in this technique is that it enhances the noise effect in the image as well.